<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Service\Group;

use App\Models\ControlList;
use App\Models\GroupOrder;
use App\Models\GroupOrderBatche;
use App\Models\GroupOrderProduct;
use App\Models\GroupOrderSession;
use App\Models\GroupOrderSetting;
use App\Models\OrderBatch;
use App\Models\User;
use App\Service\BaseService;
use App\Service\Notifications\NotificationService;
use App\Service\Pools\DividendService;
use App\Service\Setting\BeanSettingService;
use App\Service\Setting\GroupSettingService;
use App\Service\User\BeanAccountService;
use App\Service\User\PointAccountServices;
use App\Service\User\RefundService;
use App\Service\User\RewardAccountService;
use App\Service\User\SinglePoolService;
use App\Service\User\WalletAccountService;
use Illuminate\Support\Facades\DB;

class GroupService extends BaseService
{
    /**
     * 按照配置初始化每日拼团场.
     */
    public function initGroupSession()
    {
        $model = GroupOrderSession::query()->where('date', now()->toDateString())->first();
        if (! $model) {
            $gos = GroupOrderSetting::query()->first();
            $gos->session_setting->each(function ($item) {
                GroupOrderSession::query()->firstOrCreate([
                    'date' => now()->toDateString(),
                    'name' => $item['name'],
                    'start_time' => $item['startTime'],
                    'end_time' => $item['endTime'],
                ]);
            });
        }
    }

    /**
     * 每分钟检测每日拼团场.
     */
    public function checkEnabled()
    {
        now()->toTimeString();
        $gos = GroupOrderSession::query()
            ->where('date', now()->toDateString())
            ->get();
        $gos->each(function ($item) {
            if ($item->active == $item->isActive()) {
                return;
            }
            $item->active = $item->isActive();
            $item->save();
            if ($item->isActive() == 3) {
                //TODO 最近场过期 走退款程序和拼单成功程序
//                $this->dividendEligibility($item->id);
                $this->groupFailed($item->id);
                $this->groupSuccess($item->id);
            }
        });
    }
    //分红资格
    /**
     * 拼单失败.
     * @param mixed $session_id
     */
    public function groupFailed($session_id)
    {
        $refund = RefundService::make();
        OrderBatch::query()
            ->where('session_id', $session_id)
            ->where('status', 0)
            ->chunkById(500, function ($models) use ($refund) {
                $models->each(function ($model) use ($refund) {
                    $refund->initiateRefund($model);
                });
            });
    }

    /**
     * 拼单成功
     * @param mixed $session_id
     */
    public function groupSuccess($session_id)
    {
        GroupOrder::query()
            ->where('session_id', $session_id)
            ->where('status', 1)
            ->where('is_winner', 1)
            ->chunkById(200, function ($models) {
                $models->each(function ($model) {
                    BeanAccountService::make()->initBeanReward($model);
                });
            });
    }

    public function dividendEligibility($session_id)
    {
        // 第一步：重置所有用户状态（高效方式）
        User::query()->where('is_dividend', 1)->update(['is_dividend' => 0]);

        // 第二步：处理 participate_dividend = 0 且无订单的用户
        User::query()->where('agent_level', '>', 0)
            ->whereExists(function ($query) {
                $query->select(DB::raw(1))
                    ->from('performance_levels')
                    ->whereColumn('performance_levels.id', 'users.agent_level')
                    ->where('performance_levels.participate_dividend', 0);
            })
            ->update(['is_dividend' => 1]);

        // 第三步：处理满足订单数量要求的用户
        User::query()->where('agent_level', '>', 0)
            ->whereExists(function ($query) {
                $query->select(DB::raw(1))
                    ->from('performance_levels')
                    ->whereColumn('performance_levels.id', 'users.agent_level')
                    ->where('performance_levels.participate_dividend', '>', 0);
            })
            ->whereExists(function ($query) use ($session_id) {
                $query->select(DB::raw(1))
                    ->from('order_batches')
                    ->whereColumn('order_batches.user_id', 'users.id')
                    ->where('order_batches.session_id', $session_id)
                    ->whereRaw('order_batches.order_count >= (
                SELECT participate_dividend
                FROM performance_levels
                WHERE id = users.agent_level
            )');
            })
            ->update(['is_dividend' => 1]);
    }

    //结算拼团
    public function checkGroupBatches()
    {
        $winning_settings = GroupOrderSetting::query()->first()->winning_settings;
        GroupOrderBatche::with('product')
            ->where('end_date', '<=',now())
            ->where('status', 0)
            ->get()->each(function ($item) use($winning_settings) {

                if ($item->type == 2){
                    $seeting = $winning_settings[$item->batch - 1];
                    //给分红积分
                    $bean = $seeting['bean'];
                    SinglePoolService::make()->recharge($item->user_id, $seeting['number']);
                    BeanAccountService::make()->recharge($item->user_id, $bean,'拼团奖励通证:'.$bean);
                    DividendService::make()->injectFunds($item->product->price); //进入分红池
                }
                $item->status = 1;
                $item->save();
            });

    }

    //商品回收
    public function commodityRecycling()
    {
        $ra =  RewardAccountService::make();
        GroupOrderBatche::query()
            ->where('status', 1)
            ->where('type', 1)
            ->where('for_sale', 1)
            ->chunkById(500, function ($models) use($ra){
                foreach ($models as $model) {
//                        $amount = $model->reward_amount;
//                        $pa = PointAccountServices::make()->consumption($model->user_id, $amount, '商品寄售成功 绿色积分转换奖励余额:' . $amount);
//                        if ($pa) {
//                        }else {
//                            $user = User::query()->find($model->user_id);
//                            NotificationService::make()->SystemNotify($user, '由于积分不足商品寄售成功 积分转换失败');
//                        }
                    $ra->recharge($model->user_id,$model->reward_amount,6,'商品寄售成功 获取奖励余额:'.$model->reward_amount);

                    $model->for_sale = 2;
                    $model->save();
                }
            });
    }


    public function createAGroupBuyingOrder(
        User $user,
        GroupOrderSession $groupOrderSession,
        GroupOrderProduct $groupOrderProduct,
        $is_makeAnAppointment = 2,
        $number = 1,
        $advance_card,
        $lastGroupOrder
    ) {
        //TODO 分析用户 查场次时间 查钱 查豆豆 查中单率
        $productPrice = $groupOrderProduct->price;
        $productPrice = bcmul($productPrice, $number, 2);
        $setting = BeanSettingService::make()->getSetting();
        $paymentBean = bcdiv($productPrice, $setting['PRICE'], 2); //KC通证价格换算
        $bean = bcmul($paymentBean, $setting['PAYMENT'], 2); //支付总价百分比的数量 unit_price burn
        $bean_unit_price = $setting['PRICE'];  //KC通证单价
        $burn = bcmul($paymentBean, $setting['PAYMENT'], 2);
        if (BeanAccountService::make()->checkTheBalance($user->id) < $bean) {
            $this->ExitResponse('KC通证余额不足！', 7);
        }

        //TODO确定是否中单
        $winData = $this->winOrNot($user->id, $lastGroupOrder);
        if ($advance_card) {
            return DB::transaction(function () use ($winData, $advance_card, $is_makeAnAppointment, $bean_unit_price, $burn, $user, $groupOrderSession, $groupOrderProduct, $bean, $productPrice, $number) {
                BeanAccountService::make()->consumption($user->id, $bean, sprintf('拼单KC通证消费:%s', $bean));
                $go = GroupOrder::query()->create([
                    'user_id' => $user->id,
                    'session_id' => $groupOrderSession->id,
                    'product_id' => $groupOrderProduct->id,
                    'order_no' => genOrderNumber(),
                    'amount' => $productPrice,
                    'gold_amount' => $bean,
                    'number' => $number,
                    'is_winner' => $winData['is_win'],
                    'is_forced' => $winData['is_forced'] ?? 0,
                    'user_order_count' => $winData['user_order_count'],
                    'bean_unit_price' => $bean_unit_price,
                    'bean_burn' => $burn,
                    'make_an_appointment' => $is_makeAnAppointment,
                    'is_card' => 1,
                    'card_id' => $advance_card->id,
                ]);
                $advance_card->decrement('remainder_count');
                return $go;
            });
        } else {
            if (WalletAccountService::make()->checkTheBalance($user->id) < $productPrice) {
                $this->ExitResponse('钱包余额不足！', 7);
            }
            //扣钱 豆豆
            return DB::transaction(function () use ($winData, $is_makeAnAppointment, $bean_unit_price, $burn, $user, $groupOrderSession, $groupOrderProduct, $bean, $productPrice, $number) {
                WalletAccountService::make()->consumption($user->id, $productPrice, '拼单钱包消费:' . $productPrice, 2);
                BeanAccountService::make()->consumption($user->id, $bean, sprintf('拼单KC通证消费:%s', $bean));
                return GroupOrder::query()->create([
                    'user_id' => $user->id,
                    'session_id' => $groupOrderSession->id,
                    'product_id' => $groupOrderProduct->id,
                    'order_no' => genOrderNumber(),
                    'amount' => $productPrice,
                    'gold_amount' => $bean,
                    'number' => $number,
                    'is_winner' => $winData['is_win'],
                    'is_forced' => $winData['is_forced'] ?? 0,
                    'user_order_count' => $winData['user_order_count'],
                    'bean_unit_price' => $bean_unit_price,
                    'bean_burn' => $burn,
                    'make_an_appointment' => $is_makeAnAppointment,
                ]);
            });
        }
    }

    /**
     * 推算中单.
     * @param $user_id
     * @param mixed $groupOrder
     * @return array|int[]|void
     */
    public function winOrNot($user_id, $groupOrder)
    {
        $isList = ControlList::query()->where('user_id', $user_id)->first();
        //查询该人最近下单量

        $user_order_count = $groupOrder->user_order_count ?? 0;
        ++$user_order_count;  //定义本单是否中
        if ($isList) {
            //在名单 查询第一优先级 在查询第二优先权
            switch ($isList->status) {
                case 0:
                    //正常 返回control 中单数
                    $control = $isList->control;
                    if ($user_order_count >= $control) {
                        //中了
                        return [
                            'user_order_count' => 0, //此单归零
                            'is_win' => 1,
                            'is_forced' => 1,
                        ];
                    }
                    //没中
                    return [
                        'user_order_count' => $user_order_count,
                        'is_win' => 0,
                    ];

                    break;
                case 1:
                    //必中
                    return [
                        'user_order_count' => 0, //此单归零
                        'is_win' => 1,
                        'is_forced' => 1,
                    ];
                    break;
                case 2:
                    //必不中
                    //没中
                    return [
                        'user_order_count' => $user_order_count,
                        'is_win' => 0,
                    ];
                    break;
            }
        } else {
            //获取正常中单数
            $winInterval = GroupOrderSetting::query()->first()->win_interval;
            if ($user_order_count >= $winInterval) {
                //中了
                return [
                    'user_order_count' => 0, //此单归零
                    'is_win' => 1,
                ];
            }
            //没中
            return [
                'user_order_count' => $user_order_count,
                'is_win' => 0,
            ];
        }
    }
}
